import 'dart:async';

import 'package:ad_common/third_ad.dart';
import 'package:ad_common/third_ad_instance.dart';
import 'package:ad_common/util/log.dart';
import 'package:anythink_sdk/at_index.dart';
import 'package:top_on_ad_plugin/top_on_base_ad.dart';

/// FileName top_on_native_ad
/// @Author zhuqingfang
/// @Date 2022/9/30 3:57 下午
/// @Description top on native ad
//ad request map
Map<String, TopOnNativeAd> _nativeAdRequest = {};

//ad loaded map
Map<String, TopOnNativeAd> _nativeAdLoaded = {};

//ad show object
TopOnNativeAd? _nativeAdShow;
//为空初始化，不空，不初始化，确保listener只注册一次
StreamSubscription? _initNativeAdListener;

class TopOnNativeAd extends TopOnBaseAd {
  TopOnNativeAd({required ThirdAdParams thirdAdParams})
      : super(thirdAdParams: thirdAdParams);

  @override
  void load() {
    //在父类执行top on sdk 初始化
    super.load();

    //注册监听回调，只初始化一次
    _initNativeAdListener = _initNativeAdListener ?? _nativeAdListener();

    //检查广告状态，如果广告正在加载中或者placementId对应的广告已经准备好，不执行加载,否则加载广告
    checkAdState(
        thirdAdType: ThirdAdType.topOnNativeAd,
        placementId: thirdAdParams.placementId,
        isLoaded: (isLoaded) {
          if (isLoaded == true) {
            //如果对应的placementId 有对应的广告缓存，不再请求广告
            thirdAdParams.thirdAdEventCallback(
                AdCallbackEvent.loadFail,
                '${thirdAdParams.placementId} top on banner ad is loading',
                {thirdAdParams.placementId: 'isLoading'});
          } else {
            //一个 placementId 对应一个实例，缓存起来，只有真正发起广告请求的时候才缓存
            _nativeAdRequest[thirdAdParams.placementId] = this;

            //请求广告
            _loadNativeAd(thirdAdParams: thirdAdParams);
          }
        });
  }

  @override
  void show() {
    isShowTopOnAd(
        thirdAdType: ThirdAdType.topOnNativeAd,
        placementId: thirdAdParams.placementId,
        isShowAd: (isShowAd) {
          if (isShowAd == true) {
            if (_nativeAdLoaded.containsKey(thirdAdParams.placementId)) {
              _nativeAdShow = _nativeAdLoaded[thirdAdParams.placementId];
            }
            //获取native widget
            if (thirdAdParams.nativeParams!.isTemplateRender == false) {
              thirdAdParams.nativeParams?.thirdNativeAdOutputWidget =
                  PlatformNativeWidget(thirdAdParams.placementId, {
                ATNativeManager.parent():
                    ATNativeManager.createNativeSubViewAttribute(
                        thirdAdParams.nativeParams!.parentViewAttribute.width,
                        thirdAdParams.nativeParams!.parentViewAttribute.height,
                        backgroundColorStr: thirdAdParams.nativeParams!
                            .parentViewAttribute.backgroundColorStr!),
                ATNativeManager.appIcon():
                    ATNativeManager.createNativeSubViewAttribute(
                        thirdAdParams.nativeParams!.appIconAttribute!.width,
                        thirdAdParams.nativeParams!.appIconAttribute!.height,
                        x: thirdAdParams.nativeParams!.appIconAttribute!.x!,
                        y: thirdAdParams.nativeParams!.appIconAttribute!.y!,
                        backgroundColorStr: thirdAdParams.nativeParams!
                            .appIconAttribute!.backgroundColorStr!),
                ATNativeManager.mainTitle():
                    ATNativeManager.createNativeSubViewAttribute(
                        thirdAdParams.nativeParams!.mainTitleAttribute!.width,
                        thirdAdParams.nativeParams!.mainTitleAttribute!.height,
                        x: thirdAdParams.nativeParams!.mainTitleAttribute!.x!,
                        y: thirdAdParams.nativeParams!.mainTitleAttribute!.y!,
                        textSize: thirdAdParams
                            .nativeParams!.mainTitleAttribute!.textSize!,
                        textColorStr: thirdAdParams
                            .nativeParams!.mainTitleAttribute!.textColorStr!),
                ATNativeManager.desc():
                    ATNativeManager.createNativeSubViewAttribute(
                        thirdAdParams.nativeParams!.descAttribute!.width,
                        thirdAdParams.nativeParams!.descAttribute!.height,
                        x: thirdAdParams.nativeParams!.descAttribute!.x!,
                        y: thirdAdParams.nativeParams!.descAttribute!.y!,
                        textSize: thirdAdParams
                            .nativeParams!.descAttribute!.textSize!,
                        textColorStr: thirdAdParams
                            .nativeParams!.descAttribute!.textColorStr!),
                ATNativeManager.cta():
                    ATNativeManager.createNativeSubViewAttribute(
                        thirdAdParams.nativeParams!.ctaAttribute!.width,
                        thirdAdParams.nativeParams!.ctaAttribute!.height,
                        x: thirdAdParams.nativeParams!.ctaAttribute!.x!,
                        y: thirdAdParams.nativeParams!.ctaAttribute!.y!,
                        textSize: thirdAdParams
                            .nativeParams!.ctaAttribute!.textSize!,
                        textColorStr: thirdAdParams
                            .nativeParams!.ctaAttribute!.textColorStr!,
                        backgroundColorStr: thirdAdParams
                            .nativeParams!.ctaAttribute!.backgroundColorStr!),
                ATNativeManager.mainImage():
                    ATNativeManager.createNativeSubViewAttribute(
                        thirdAdParams.nativeParams!.mainImageAttribute!.width,
                        thirdAdParams.nativeParams!.mainImageAttribute!.height,
                        x: thirdAdParams.nativeParams!.mainImageAttribute!.x!,
                        y: thirdAdParams.nativeParams!.mainImageAttribute!.y!,
                        backgroundColorStr: thirdAdParams.nativeParams!
                            .mainImageAttribute!.backgroundColorStr!),
                ATNativeManager.adLogo():
                    ATNativeManager.createNativeSubViewAttribute(
                        thirdAdParams.nativeParams!.adLogoAttribute!.width,
                        thirdAdParams.nativeParams!.adLogoAttribute!.height,
                        x: thirdAdParams.nativeParams!.adLogoAttribute!.x!,
                        y: thirdAdParams.nativeParams!.adLogoAttribute!.y!,
                        backgroundColorStr: thirdAdParams.nativeParams!
                            .adLogoAttribute!.backgroundColorStr!),
                ATNativeManager.dislike():
                    ATNativeManager.createNativeSubViewAttribute(
                        thirdAdParams.nativeParams!.dislikeAttribute!.width,
                        thirdAdParams.nativeParams!.dislikeAttribute!.height,
                        x: thirdAdParams.nativeParams!.dislikeAttribute!.x!,
                        y: thirdAdParams.nativeParams!.dislikeAttribute!.y!)
              });
            } else {
              if (thirdAdParams.nativeParams!.isAdaptiveHeight == false) {
                thirdAdParams.nativeParams!.thirdNativeAdOutputWidget =
                    PlatformNativeWidget(thirdAdParams.placementId, const {});
              } else {
                thirdAdParams.nativeParams!.thirdNativeAdOutputWidget =
                    PlatformNativeWidget(
                  thirdAdParams.placementId,
                  const {},
                  isAdaptiveHeight: true,
                );
              }
            }

            //已获取第三方广告banner widget 通知业务刷新UI，展示广告
            thirdAdParams.thirdAdEventCallback(
                AdCallbackEvent.renderSuccess,
                '${thirdAdParams.placementId} top on native ad widget get',
                null);
          } else {
            //广告没准备好，无法展示
            Map<String, Object> infoMap = {
              thirdAdParams.placementId: 'notReady'
            };
            thirdAdParams.thirdAdEventCallback(
                AdCallbackEvent.showFail,
                '${thirdAdParams.placementId} top on native ad is notReady',
                infoMap);
          }
        });
  }
}

_loadNativeAd({required ThirdAdParams thirdAdParams}) {
  if (thirdAdParams.nativeParams!.isAdaptiveHeight == false) {
    ATNativeManager.loadNativeAd(
        placementID: thirdAdParams.placementId,
        extraMap: {
          ATNativeManager.parent():
              ATNativeManager.createNativeSubViewAttribute(
            thirdAdParams.nativeParams!.parentViewAttribute.width,
            thirdAdParams.nativeParams!.parentViewAttribute.height,
          ),
        });
  } else {
    ATNativeManager.loadNativeAd(
        placementID: thirdAdParams.placementId,
        extraMap: {
          ATNativeManager.parent():
              ATNativeManager.createNativeSubViewAttribute(
            thirdAdParams.nativeParams!.parentViewAttribute.width,
            thirdAdParams.nativeParams!.parentViewAttribute.height,
          ),
          ATNativeManager.isAdaptiveHeight(): true
        });
  }
}

//检查已缓存的广告状态信息
_checkNativeAdStatus({required String placementId}) {
  return ATNativeManager.checkNativeAdLoadStatus(placementID: placementId);
}

//获取已缓存广告的信息，目前仅供测试看日志用
_getNativeValidAds({required String placementId}) {
  ATNativeManager.getNativeValidAds(placementID: placementId).then((value) =>
      Log.i('insert video ad $placementId all available ad info:$value'));
}

StreamSubscription _nativeAdListener() {
  return ATListenerManager.nativeEventHandler.listen((value) async {
    switch (value.nativeStatus) {
      //广告加载失败
      case NativeStatus.nativeAdFailToLoadAD:
        Log.i(
            "flutter nativeAdFailToLoadAD ---- placementID: ${value.placementID} ---- errStr:${value.requestMessage}");
        if (_nativeAdRequest.containsKey(value.placementID)) {
          Map<String, Object> infoMap = {value.placementID: 'loadFail'};
          _nativeAdRequest[value.placementID]?.thirdAdParams.thirdAdEventCallback(
              AdCallbackEvent.loadFail,
              'top on native ad placementID :${value.placementID} load fail errStr:${value.requestMessage}',
              infoMap);
        }
        break;
      //广告加载成功
      case NativeStatus.nativeAdDidFinishLoading:
        Log.i(
            "flutter nativeAdDidFinishLoading ---- placementID: ${value.placementID}");
        if (_nativeAdRequest.containsKey(value.placementID)) {
          _nativeAdLoaded[value.placementID] =
              _nativeAdRequest[value.placementID]!;
          final adState =
              await _checkNativeAdStatus(placementId: value.placementID);
          _nativeAdLoaded[value.placementID]
              ?.thirdAdParams
              .thirdAdEventCallback(
                  AdCallbackEvent.loadSuccess,
                  'top on native ad placementID:${value.placementID}  loaded',
                  adState['adInfo']);
        }
        _getNativeValidAds(placementId: value.placementID);
        break;
      //广告被点击
      case NativeStatus.nativeAdDidClick:
        Log.i(
            "flutter nativeAdDidClick ---- placementID: ${value.placementID} ---- extra:${value.extraMap}");
        _nativeAdShow?.thirdAdParams.thirdAdEventCallback(
            AdCallbackEvent.onClick,
            'top on native ad placementID:${value.placementID}  onClick',
            value.extraMap);
        break;
      //Deeplink
      case NativeStatus.nativeAdDidDeepLink:
        Log.i(
            "flutter nativeAdDidDeepLink ---- placementID: ${value.placementID} ---- extra:${value.extraMap} ---- isDeeplinkSuccess:${value.isDeeplinkSuccess}");
        break;
      //广告视频结束播放，部分广告平台有此回调
      case NativeStatus.nativeAdDidEndPlayingVideo:
        Log.i(
            "flutter nativeAdDidEndPlayingVideo ---- placementID: ${value.placementID} ---- extra:${value.extraMap}");
        break;
      //广告进入全屏播放，仅iOS有此回调
      case NativeStatus.nativeAdEnterFullScreenVideo:
        Log.i(
            "flutter nativeAdEnterFullScreenVideo ---- placementID: ${value.placementID} ---- extra:${value.extraMap}");
        break;
      //广告离开全屏播放，仅iOS有此回调
      case NativeStatus.nativeAdExitFullScreenVideoInAd:
        Log.i(
            "flutter nativeAdExitFullScreenVideoInAd ---- placementID: ${value.placementID} ---- extra:${value.extraMap}");
        break;
      //广告展示成功
      case NativeStatus.nativeAdDidShowNativeAd:
        Log.i(
            "flutter nativeAdDidShowNativeAd ---- placementID: ${value.placementID} ---- extra:${value.extraMap}");
        _nativeAdShow?.thirdAdParams.thirdAdEventCallback(
            AdCallbackEvent.onShow,
            'top on native ad placementID:${value.placementID}  onShow',
            value.extraMap);
        break;
      //广告视频开始播放，部分广告平台有此回调
      case NativeStatus.nativeAdDidStartPlayingVideo:
        Log.i(
            "flutter nativeAdDidStartPlayingVideo ---- placementID: ${value.placementID} ---- extra:${value.extraMap}");
        break;
      //广告关闭按钮被点击，部分广告平台有此回调
      case NativeStatus.nativeAdDidTapCloseButton:
        Log.i(
            "flutter nativeAdDidTapCloseButton ---- placementID: ${value.placementID} ---- extra:${value.extraMap}");
        _nativeAdShow?.thirdAdParams.thirdAdEventCallback(
            AdCallbackEvent.onClose,
            'top on native ad placementID:${value.placementID}  onDismiss',
            value.extraMap);
        break;
      case NativeStatus.nativeAdDidCloseDetailInAdView:
        Log.i(
            "flutter nativeAdDidCloseDetailInAdView ---- placementID: ${value.placementID} ---- extra:${value.extraMap}");
        _nativeAdShow?.thirdAdParams.thirdAdEventCallback(
            AdCallbackEvent.onClose,
            'top on native ad placementID:${value.placementID}  onDismiss',
            value.extraMap);
        break;
      //广告加载Draw成功，仅iOS有此回调
      case NativeStatus.nativeAdDidLoadSuccessDraw:
        Log.i(
            "flutter nativeAdDidLoadSuccessDraw ---- placementID: ${value.placementID} ---- extra:${value.extraMap}");
        break;
      case NativeStatus.nativeAdUnknown:
        Log.i("flutter downloadUnknown");
        break;
    }
  });
}
